package com.zhihuishu.micro.course.service.impl;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.zhihuishu.micro.course.dao.ScoreAssessRuleMapper;
import com.zhihuishu.micro.course.helper.RedisKeyHelper;
import com.zhihuishu.micro.course.model.ScoreAssessRule;
import com.zhihuishu.micro.course.service.ScoreAssessRuleService;
import com.zhihuishu.toolkit.helper.BeanHelper;
import com.zhihuishu.toolkit.jedis.JedisHelper;
import com.zhihuishu.toolkit.jedis.JedisHelper.Handler;

import redis.clients.jedis.Jedis;
@Service("scoreAssessRuleService")
public class ScoreAssessRuleServiceImpl extends BaseService implements ScoreAssessRuleService {
	
	@Resource
	private ScoreAssessRuleMapper scoreAssessRuleMapper ;
	
	// 缓存有效期
	private final int DEFAULT_EXPIRE = 7200 ;
	
	@Override
	public int findScoreAssessRuleCount(Long courseId) {
		
		return scoreAssessRuleMapper.findScoreAssessRuleCount(courseId);
	}
	
	/**
	 * 从数据库查询ScoreAssessRule对象
	 * @author Rain
	 * @time 2016年10月24日-下午3:05:05
	 * @param courseId
	 * @return
	 */
	public ScoreAssessRule loadScoreAssessRule(Long courseId){
		List<ScoreAssessRule> list = scoreAssessRuleMapper.findByCourseId(courseId);
		if (!CollectionUtils.isEmpty(list)) {
			return list.get(0);
		}
		return null;
	}
	
	@Override
	public ScoreAssessRule findByCourseId(Long courseId) {
		Assert.notNull(courseId,"courseId must not be null");
		
		ScoreAssessRule scoreAssessRule = this.getRedisScoreAssessRuleData(courseId);
		
		if (null == scoreAssessRule){
			return this.setRedisScoreAssessRuleData(courseId);
		}
		
		return scoreAssessRule;
	}
	
	@Transactional
	public ScoreAssessRule save(ScoreAssessRule scoreAssessRule) throws Exception{
		Assert.notNull(scoreAssessRule,"scoreAssessRule must not be null");
		Assert.notNull(scoreAssessRule.getCourseId(),"scoreAssessRule.getCourseId() must not be null");
		
		// 唯一性验证
		ScoreAssessRule scoreassessrule = this.findByCourseId(scoreAssessRule.getCourseId().longValue());
		
		if (null != scoreassessrule) {
			throw new RuntimeException("Course with ID: " + scoreAssessRule.getCourseId() + " existing appraisal standards, cannot at the same time there are two standard");
		}
		
		scoreAssessRuleMapper.save(scoreAssessRule);
		
		scoreAssessRule = this.setRedisScoreAssessRuleData(scoreAssessRule.getCourseId());
		
		return scoreAssessRule;
	}
	
	@Transactional
	public ScoreAssessRule update(ScoreAssessRule scoreAssessRule) {
		Assert.notNull(scoreAssessRule,"scoreAssessRule must not be null");
		Assert.notNull(scoreAssessRule.getCourseId(),"scoreAssessRule.getCourseId() must not be null");
		Assert.notNull(scoreAssessRule.getId(),"scoreAssessRule.getId() must not be null");
		
		scoreAssessRuleMapper.update(scoreAssessRule);
		
		this.removeCache(scoreAssessRule.getCourseId());
		
		scoreAssessRule = this.setRedisScoreAssessRuleData(scoreAssessRule.getCourseId());
		
		return scoreAssessRule;
	}
	
	@Transactional
	public void remove(Long courseId) {
		Assert.notNull(courseId,"courseId must not be null");
		
		ScoreAssessRule scoreAssessRule = this.getRedisScoreAssessRuleData(courseId);
		scoreAssessRuleMapper.remove(Long.valueOf(scoreAssessRule.getId()));
		
		// 删除缓存
		this.removeCache(Long.valueOf(scoreAssessRule.getId()));
		
		if (null != scoreAssessRule) {
			this.removeCache(scoreAssessRule.getCourseId());
		}
	}
	
	/**
	 * 存值(ScoreAssessRule)对象到redis
	 * @author Rain
	 * @time 2016年10月24日-下午3:17:34
	 * @param courseId
	 * @return
	 */
	public ScoreAssessRule setRedisScoreAssessRuleData(final long courseId) {
		ScoreAssessRule scoreAssessRule = this.loadScoreAssessRule(courseId);
		
		if (null == scoreAssessRule) {
			return null;
		}
		
		final Map<String, String> map = BeanHelper.describe(scoreAssessRule);
		if (!CollectionUtils.isEmpty(map)) {
			jedisExecutor.execute( new Handler() {
				@Override
				public void handle(Jedis jedis) {
					jedis.hmset(RedisKeyHelper.getScoreAssessRuleKey(courseId), map);
					jedis.expire(RedisKeyHelper.getScoreAssessRuleKey(courseId), DEFAULT_EXPIRE);
				}
			});
		}
		
		return scoreAssessRule;
	} 
	
	/**
	 * 获取redis中的数据 (ScoreAssessRule)
	 * @author Rain
	 * @time 2016年10月24日-下午3:14:49
	 * @param courseId
	 * @return
	 */
	public ScoreAssessRule getRedisScoreAssessRuleData(final long courseId){
		final ScoreAssessRule scoreAssessRule = new ScoreAssessRule();
		jedisExecutor.execute( new Handler() {
			@Override
			public void handle(Jedis jedis) {
				ScoreAssessRule dto = null;
				String key = RedisKeyHelper.getScoreAssessRuleKey(courseId);
				if (jedis.exists(key)) {
					// 如果Key存在，将信息转换为考核标准对象
					Map<String, String> map = jedis.hgetAll(key);
					if (!CollectionUtils.isEmpty(map) && map.get("id") != null) {
						dto = BeanHelper.transTo(map, ScoreAssessRule.class);
					}
				}
				if (dto != null && dto.getId() != null) {
					BeanHelper.copyProperties(dto, scoreAssessRule);
				}
			}
		});
		return scoreAssessRule.getId() != null ? scoreAssessRule : null;
	}

	/**
	 * 删除考核标准对象缓存
	 * @author Rain
	 * @time 2016年10月24日-下午3:14:16
	 * @param courseId
	 */
	private void removeCache(final long courseId) {
		jedisExecutor.execute( new Handler() {
			@Override
			public void handle(Jedis jedis) {
				jedis.del(RedisKeyHelper.getScoreAssessRuleKey(courseId));
			}
		});
	}

}
